/**
 * Company:湖南省汇聚赢农业开发有限公司
 */

package com.hunhjy.wx.wxsdk.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.hunhjy.core.kit.PropKit;
import com.hunhjy.wx.wxsdk.aes.AesException;

/**
 * @Description: 微信服务器 验证签名
 * @author ZhuoQi_Zou
 * @date 2016年6月26日 上午1:38:26
 *
 */

public class SignatureCheckUtil {
	// 日志记录
	private static Logger logger = LogManager.getLogger(SignatureCheckUtil.class);

	public static final SignatureCheckUtil me = new SignatureCheckUtil();

	/**
	 * 验证签名
	 * 
	 * @throws NoSuchAlgorithmException
	 * @throws AesException
	 */
	public String checkSignature(HttpServletRequest request) throws NoSuchAlgorithmException, AesException {
		String token = PropKit.get("wechart.token");// 与微信接口配置信息中的Token要一致
		String timestamp = request.getParameter("timestamp"); // 时间戳
		String nonce = request.getParameter("nonce");// 随机数
		String signature = request.getParameter("signature");// 微信加密签名
		String echostr = request.getParameter("echostr");// 随机字符串，需要返回

		if (signature == null || signature.length() > 128 || timestamp == null || timestamp.length() > 128
				|| nonce == null || nonce.length() > 128) {
			logger.error("接入微信服务器认证的加密参数为空或是长度大于128.");
			throw new AesException(AesException.ValidateSignatureError);
		}

		String[] arr = new String[] { token, timestamp, nonce };
		// 将token、timestamp、nonce三个参数进行字典序排序
		Arrays.sort(arr);
		StringBuilder content = new StringBuilder();
		for (int i = 0; i < arr.length; i++) {
			content.append(arr[i]);
		}
		MessageDigest md = null;
		String tmpStr = null;

		md = MessageDigest.getInstance("SHA-1");
		// 将三个参数字符串拼接成一个字符串进行sha1加密
		byte[] digest = md.digest(content.toString().getBytes());
		tmpStr = byteToStr(digest);

		// 将sha1加密后的字符串可与signature对比，标识该请求来源于微信
		boolean isOk = tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
		if (!isOk) {
			echostr = "";
			logger.debug("微信服务器验证失败！");
		}
		return echostr;
	}

	/**
	 * 将字节数组转换为十六进制字符串
	 * 
	 * @param byteArray
	 * @return
	 */
	private String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	/**
	 * 将字节转换为十六进制字符串
	 * 
	 * @param mByte
	 * @return
	 */
	private String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];
		String s = new String(tempArr);
		return s;
	}

}
